package com.xinhe.web.service;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.xinhe.web.common.Result;
import com.xinhe.web.entity.QGoods;
import com.xinhe.web.entity.QSeckillGoods;
import com.xinhe.web.entity.QSeckillTime;
import com.xinhe.web.entity.SeckillGoods;
import com.xinhe.web.reposity.SeckillGoodsRepository;
import com.xinhe.web.response.SeckillGoodsView;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.inject.Provider;
import javax.persistence.EntityManager;
import java.util.Objects;

@Service
public class SeckillGoodsService {
    @Autowired
    private SeckillGoodsRepository seckillGoodsRepository;
    //查询工厂
    private JPAQueryFactory queryFactory;
    @Autowired
    private Provider<EntityManager> entityManager;

    @PostConstruct
    public void init() {
        queryFactory = new JPAQueryFactory(entityManager);
    }

    public QueryResults<SeckillGoodsView> pageSeckillGoods(Long goodsId,Long seckillTimeId,String remark,
                                                           Long sellerUserId,String keyword) {
        QSeckillGoods qSeckillGoods = QSeckillGoods.seckillGoods;
        QSeckillTime qSeckillTime = QSeckillTime.seckillTime;
        QGoods qGoods = QGoods.goods;
        BooleanBuilder builder = new BooleanBuilder();
        //builder.and(qShop.removed.eq(0));
        if (!Objects.isNull(goodsId)) {
            builder.and(qSeckillGoods.goodsId.eq(goodsId));
        }
        if (!Objects.isNull(seckillTimeId)) {
            builder.and(qSeckillGoods.seckillTimeId.eq(seckillTimeId));
        }
        if (!Objects.isNull(sellerUserId)) {
            builder.and(qGoods.sellerUserId.eq(sellerUserId));
        }
        if (StringUtils.isNotBlank(keyword)) {
            builder.and(qGoods.name.contains(keyword));
        }
        String concatString = "-";//'%H:%i'
        String dateFormat = "%H:%i";
        return queryFactory.select(
                Projections.bean(
                        SeckillGoodsView.class,
                        qSeckillGoods.id,
                        qGoods.id.as("goodsId"),
                        qGoods.iconPath,
                        qGoods.name,
                        qGoods.dis,
                        qGoods.price,
                        qSeckillGoods.seckillTimeId,
                        ExpressionUtils.as(
                                Expressions.stringTemplate("concat('{0}',date_format({1}, '{2}'), date_format({3}, '{4}'))",
                                        concatString,qSeckillTime.startTime, dateFormat,qSeckillTime.endTime, dateFormat),
                                "timeSlot")
                )
        ).from(qSeckillGoods)
                .leftJoin(qSeckillTime).on(qSeckillGoods.seckillTimeId.eq(qSeckillTime.id))
                .leftJoin(qGoods).on(qSeckillGoods.goodsId.eq(qGoods.id))
                .where(builder).limit(2)//设置查询两条记录
                .fetchResults();
    }


    public QueryResults<SeckillGoodsView> pageSeckillGoodsBySeller(Long goodsId,Long seckillTimeId,String remark,
                                                                 Long sellerUserId,String keyword) {
        //sellerUserId = this.userSessionManager.getUserId();
        QSeckillGoods qSeckillGoods = QSeckillGoods.seckillGoods;
        QSeckillTime qSeckillTime = QSeckillTime.seckillTime;
        QGoods qGoods = QGoods.goods;
        BooleanBuilder builder = new BooleanBuilder();
        //builder.and(qShop.removed.eq(0));
        if (!Objects.isNull(goodsId)) {
            builder.and(qSeckillGoods.goodsId.eq(goodsId));
        }
        if (!Objects.isNull(seckillTimeId)) {
            builder.and(qSeckillGoods.seckillTimeId.eq(seckillTimeId));
        }
        if (!Objects.isNull(sellerUserId)) {
            builder.and(qGoods.sellerUserId.eq(sellerUserId));
        }
        if (StringUtils.isNotBlank(keyword)) {
            builder.and(qGoods.name.contains(keyword));
        }
        String concatString = "-";//'%H:%i'
        String dateFormat = "%H:%i";
        return queryFactory.select(
                Projections.bean(
                        SeckillGoodsView.class,
                        qSeckillGoods.id,
                        qGoods.id.as("goodsId"),
                        qGoods.iconPath,
                        qGoods.name,
                        qGoods.dis,
                        qGoods.price,
                        qSeckillGoods.seckillTimeId,
                        ExpressionUtils.as(
                                Expressions.stringTemplate("concat('{0}',date_format({1}, '{2}'), date_format({3}, '{4}'))",
                                        concatString,qSeckillTime.startTime, dateFormat,qSeckillTime.endTime, dateFormat),
                                "timeSlot")
                )
        ).from(qSeckillGoods)
                .leftJoin(qSeckillTime).on(qSeckillGoods.seckillTimeId.eq(qSeckillTime.id))
                .leftJoin(qGoods).on(qSeckillGoods.goodsId.eq(qGoods.id))
                .where(builder).limit(2)//设置查询两条记录
                .fetchResults();
    }


    @Transactional
    //@ANoRepeatRequest
    public Result saveSeckillGoods(Long goodsId, Long seckillTimeId,String remark) {
        SeckillGoods seckillGoods = this.seckillGoodsRepository.findByGoodsIdAndSeckillTimeId(goodsId,seckillTimeId);
        if (seckillGoods != null) {
            return Result.failed(1001,"该时间段您已添加");
        }
        seckillGoods = new SeckillGoods();
        seckillGoods.setSeckillTimeId(seckillTimeId);
        seckillGoodsRepository.save(seckillGoods);
        return Result.ok();
    }

    public Result delete(Long seckillGoodsId) {
        seckillGoodsRepository.deleteById(seckillGoodsId);
        return Result.ok();
    }

    public Result<SeckillGoods> findById(Long seckillGoodsId) {
        return Result.ok(seckillGoodsRepository.findById(seckillGoodsId).get());
    }
}
